package cn.com.zj.rpc.provider.server;

import cn.com.zj.rpc.provider.handler.MyRpcServerHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @ClassName MyRpcServer
 * @Description 自定义rpc服务端
 * 实现 DisposableBean会在容器销毁时候调用destroy()方法，可以在其中关闭线程组
 * @Author ZikZ227412
 * @DATE 2021/12/9 7:43
 * @Version 1.0
 */
@Service
public class MyRpcServer implements DisposableBean {

    private NioEventLoopGroup bossGroup;

    private NioEventLoopGroup workerGroup;

    @Autowired
    MyRpcServerHandler myRpcServerHandler;


    public void startServer(String ip, Integer port) {
        //创建BossNioEventLoopGroup
        bossGroup = new NioEventLoopGroup(1);
        //创建workerNioEventLoopGroup
        workerGroup = new NioEventLoopGroup();
        //创建服务端启动助手
        ServerBootstrap serverBootstrap = new ServerBootstrap();
        //设置参数
        serverBootstrap.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        ChannelPipeline pipeline = socketChannel.pipeline();
                        //添加String类型的编解码器
                        pipeline.addLast(new StringDecoder());
                        pipeline.addLast(new StringEncoder());
                        //todo:添加业务处理类
                        pipeline.addLast(myRpcServerHandler);
                    }
                });
        //绑定端口，启动server
        try {
            ChannelFuture channelFuture = serverBootstrap.bind(ip, port).sync();
            System.out.println("======================"+ ip +":"+ port +"服务端启动成功=================");
            channelFuture.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            if (bossGroup != null) {
                bossGroup.shutdownGracefully();
            }
            if (workerGroup != null) {
                workerGroup.shutdownGracefully();
            }
        }

    }

    @Override
    public void destroy() {
        if (bossGroup != null) {
            bossGroup.shutdownGracefully();
        }
        if (workerGroup != null) {
            workerGroup.shutdownGracefully();
        }
    }

}
